package cn.wolfcode.business.service.impl;

import cn.wolfcode.business.domain.BusBpmnInfo;
import cn.wolfcode.business.domain.BusCarPackageAudit;
import cn.wolfcode.business.domain.BusServiceItem;
import cn.wolfcode.business.domain.vo.AuditInfoVO;
import cn.wolfcode.business.domain.vo.AuditVo;
import cn.wolfcode.business.mapper.BusServiceItemMapper;
import cn.wolfcode.business.service.IBusBpmnInfoService;
import cn.wolfcode.business.service.IBusCarPackageAuditService;
import cn.wolfcode.business.service.IBusServiceItemService;
import cn.wolfcode.common.core.domain.entity.SysUser;
import cn.wolfcode.common.utils.DateUtils;
import cn.wolfcode.common.utils.SecurityUtils;
import cn.wolfcode.system.service.ISysConfigService;
import cn.wolfcode.system.service.ISysUserService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 服务项Service业务层处理
 *
 * @author wolfcode
 * @date 2025-09-19
 */
@Service
public class BusServiceItemServiceImpl implements IBusServiceItemService {
    @Autowired
    private BusServiceItemMapper busServiceItemMapper;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private IBusCarPackageAuditService carPackageAuditService;
    @Autowired
    private IBusBpmnInfoService busBpmnInfoService;
    @Autowired
    private RuntimeService runtimeService;

    /**
     * 查询服务项
     *
     * @param id 服务项主键
     * @return 服务项
     */
    @Override
    public BusServiceItem selectBusServiceItemById(Long id) {
        return busServiceItemMapper.selectBusServiceItemById(id);
    }

    /**
     * 查询服务项列表
     *
     * @param busServiceItem 服务项
     * @return 服务项
     */
    @Override
    public List<BusServiceItem> selectBusServiceItemList(BusServiceItem busServiceItem) {
        return busServiceItemMapper.selectBusServiceItemList(busServiceItem);
    }

    @Override
    public int insertBusServiceItem(BusServiceItem busServiceItem) {
        //1.参数合理化校验
        if (busServiceItem == null) {
            throw new RuntimeException("参数异常");
        }
        if (busServiceItem.getName() == null || busServiceItem.getOriginalPrice() == null ||
                busServiceItem.getDiscountPrice() == null || busServiceItem.getCarPackage() == null ||
                busServiceItem.getServiceCatalog() == null || busServiceItem.getInfo() == null) {
            throw new RuntimeException("参数异常");
        }
        //价格合理化验证
        //原价大于等于0，且折扣大于等于0，，且折扣价格小于等于原价
        //BigDecimal运算符不能使用 > >= < <= 等
        //xx.compareTo(xx) 调用者 > 参数，返回正数1 ，调用者=参数 返回0，调用者<参数返回-1
        if (!(busServiceItem.getOriginalPrice().compareTo(BigDecimal.ZERO) >= 0
                && busServiceItem.getDiscountPrice().compareTo(BigDecimal.ZERO) >= 0
                && busServiceItem.getOriginalPrice().compareTo(busServiceItem.getDiscountPrice()) >= 0)) {
            throw new RuntimeException("原价折扣价需大于0且原价需要大于折扣价");

        }
        //3.判断插入数据是否为套餐
        if (busServiceItem.CARPACKAGE_NO.equals(busServiceItem.getCarPackage())) {
            // 不是套餐 初始化状态变为4 ——无需审核
            busServiceItem.setAuditStatus(BusServiceItem.AUDITSTATUS_NO_REQUIRED);
        } else {
            //是套餐 状态变为0——初始化
            busServiceItem.setAuditStatus(BusServiceItem.AUDITSTATUS_INIT);
            // 提高代码安全性设置，将默认的上下架装丰台设置为下架状态
            busServiceItem.setSaleStatus(BusServiceItem.SALESTATUS_OFF);
        }
        busServiceItem.setCreateTime(DateUtils.getNowDate());
        return busServiceItemMapper.insertBusServiceItem(busServiceItem);
    }

    @Override
    public int updateBusServiceItem(BusServiceItem busServiceItem) {
        //1.参数合理化校验
        if (busServiceItem == null) {
            throw new RuntimeException("参数异常");
        }
        if (busServiceItem.getName() == null || busServiceItem.getOriginalPrice() == null ||
                busServiceItem.getDiscountPrice() == null || busServiceItem.getCarPackage() == null ||
                busServiceItem.getServiceCatalog() == null || busServiceItem.getInfo() == null) {
            throw new RuntimeException("非法参数");
        }

        //价格合理化验证
        if (!(busServiceItem.getOriginalPrice().compareTo(BigDecimal.ZERO) >= 0
                && busServiceItem.getDiscountPrice().compareTo(BigDecimal.ZERO) >= 0
                && busServiceItem.getOriginalPrice().compareTo(busServiceItem.getDiscountPrice()) >= 0)) {
            throw new RuntimeException("原价折扣价需大于0且原价需要大于折扣价");
        }

        //3.验证是否套餐禁止修改
        BusServiceItem oldObj = this.selectBusServiceItemById(busServiceItem.getId());
        if (oldObj == null || oldObj.getCarPackage() == null || oldObj.getAuditStatus() == null) {
            throw new RuntimeException("参数错误");
        }

        //验证 如果这个套餐不等于数据库查出的套餐
        if (!oldObj.getCarPackage().equals(busServiceItem.getCarPackage())) {
            throw new RuntimeException("套餐不允许修改");
        }

        //上架状态禁止修改
        if (!oldObj.getSaleStatus().equals(busServiceItem.getSaleStatus())
                || BusServiceItem.SALESTATUS_ON.equals(busServiceItem.getSaleStatus())) {
            throw new RuntimeException("修改的数据必须是下架状态且上下架状态禁止修改");
        }

        //验证审批状态
        if (!oldObj.getAuditStatus().equals(busServiceItem.getAuditStatus())) {
            throw new RuntimeException("审批状态不允许修改");
        }

        if (BusServiceItem.CARPACKAGE_NO.equals(busServiceItem.getCarPackage())
                && BusServiceItem.AUDITSTATUS_AUDITING.equals(busServiceItem.getAuditStatus())) {
            throw new RuntimeException("审批中套餐禁止修改");
        }

        if (BusServiceItem.CARPACKAGE_NO.equals(busServiceItem.getCarPackage())
                && (BusServiceItem.AUDITSTATUS_APPROVED.equals(busServiceItem.getAuditStatus())
                || BusServiceItem.AUDITSTATUS_REPLY.equals(busServiceItem.getAuditStatus()))) {
            //若状态是审批通过或者审批拒绝，我们需要将状态修改为初始化
            busServiceItem.setAuditStatus(BusServiceItem.AUDITSTATUS_INIT);
            throw new RuntimeException("已通过套餐禁止修改");
        }

        return busServiceItemMapper.updateBusServiceItem(busServiceItem);
    }

    /**
     * 批量删除服务项
     *
     * @param ids 需要删除的服务项主键
     * @return 结果
     */
    @Override
    public int deleteBusServiceItemByIds(Long[] ids) {
        return busServiceItemMapper.deleteBusServiceItemByIds(ids);
    }

    @Override
    public int saleOn(Long id) {
        //1.参数合理化验证
        if (id == null) {
            throw new RuntimeException("参数错误");
        }
        BusServiceItem busServiceItem = selectBusServiceItemById(id);
        if (busServiceItem == null) {
            throw new RuntimeException("参数错误");
        }
        //  必须是下架的状态才能上架操作
        if (BusServiceItem.SALESTATUS_ON.equals(busServiceItem.getSaleStatus())) {
            throw new RuntimeException("该服务已经上架，请勿重复操作");
        }
        // 状态判断 是套餐且不是待审核状态禁止上架
        if (BusServiceItem.CARPACKAGE_YES.equals(busServiceItem.getCarPackage()) //是套餐
                && !BusServiceItem.AUDITSTATUS_APPROVED.equals(busServiceItem.getAuditStatus())) // 不是审核通过{
            throw new RuntimeException("套餐状态必须是审核通过才可以上架");
        return busServiceItemMapper.changeSaleStatus(id, BusServiceItem.SALESTATUS_ON);
    }

    @Override
    public int saleOff(Long id) {
        //1.参数合理化验证
        if (id == null) {
            throw new RuntimeException("参数错误");
        }
        BusServiceItem busServiceItem = selectBusServiceItemById(id);
        if (busServiceItem == null) {
            throw new RuntimeException("参数错误");
        }
        //  必须是上架的状态才能下架操作
        if (BusServiceItem.SALESTATUS_OFF.equals(busServiceItem.getSaleStatus())) {
            throw new RuntimeException("该服务已经下架，请勿重复操作");
        }

        return busServiceItemMapper.changeSaleStatus(id, BusServiceItem.SALESTATUS_OFF);

    }

    /**
     * 发起审批对话框数据准备
     *
     * @param id 服务项 id
     * @return 数据。
     */
    @Override
    public AuditInfoVO getAuditInfo(Long id) {
        // 参数合理化验证
        if (id == null) {
            throw new RuntimeException("非法参数");
        }
        BusServiceItem busServiceItem = this.selectBusServiceItemById(id);
        if (busServiceItem == null) {
            throw new RuntimeException("非法参数");
        }
        // 创建 VO 对象
        AuditInfoVO vo = new AuditInfoVO();
        // 封装服务项数据
        vo.setServiceItem(busServiceItem);
        // 准备店长集合并封装
        List<SysUser> shopOwnerList = userService.selectUsersByRoleKey("shopOwner");
        vo.setShopOwners(shopOwnerList);
        // 获取阈值并封装
        String discountPriceLimit = configService.selectConfigByKey("discountPriceLimit");
        vo.setDiscountPrice(new BigDecimal(discountPriceLimit));
        // 若需要封装财务数据，则必须当前的折扣价 >= 阈值(3000)
        if (busServiceItem.getDiscountPrice().compareTo(new BigDecimal(discountPriceLimit)) >= 0) {
            // 准备财务集合并封装
            List<SysUser> financeList = userService.selectUsersByRoleKey("finance");
            vo.setFinances(financeList);
        }
        return vo;
    }

    @Override
    public int startAudit(AuditVo vo) {
        // 参数合理化验证
        if(vo == null || vo.getServiceItemId() == null || vo.getShopOwnerId() == null){
            throw new RuntimeException("非法参数");
        }
        // 根据服务项 id 查询服务项信息
        BusServiceItem busServiceItem = this.selectBusServiceItemById(vo.getServiceItemId());
        if(busServiceItem == null){
            throw new RuntimeException("非法参数");
        }
        // 状态验证
        // 必须是下架
        if(BusServiceItem.SALESTATUS_ON.equals(busServiceItem.getSaleStatus())){
            throw new RuntimeException("已经上架的服务项禁止发起审核");
        }
        // 是套餐
        if(BusServiceItem.CARPACKAGE_NO.equals(busServiceItem.getCarPackage())){
            throw new RuntimeException("不是套餐的服务单项禁止发起审核");
        }
        // 状态必须是初始化
        if(!BusServiceItem.AUDITSTATUS_INIT.equals(busServiceItem.getAuditStatus())){
            throw new RuntimeException("必须状态是审核中的服务项才可以发起审核");
        }
        // 先向业务表中插入数据
        BusCarPackageAudit audit = new BusCarPackageAudit();
        audit.setServiceItemId(busServiceItem.getId());     // 服务项id
        audit.setServiceItemName(busServiceItem.getName()); // 服务项名称
        audit.setServiceItemPrice(busServiceItem.getDiscountPrice());   // 服务项折扣价
        audit.setServiceItemInfo(busServiceItem.getInfo()); // 服务项备注信息
        //  audit.setInstanceId();  启动流程实例后才可以实现
        audit.setCreatorId(SecurityUtils.getUserId().toString());   // 创建者
        audit.setInfo(vo.getInfo());        // 快照表的备注信息
        audit.setStatus(BusCarPackageAudit.STATUS_IN_PROGRESS); // 快照表状态
        // 插入业务数据
        carPackageAuditService.insertBusCarPackageAudit(audit);
        // 启动流程实例就需要流程定义的 Key 和 version。
        // 那我们可以根据实体类中的固定类型来查询流程 BpmnInfo对象，然后拿到 key 和 version。
        BusBpmnInfo info = busBpmnInfoService.selectBusBpmnInfoByType(BusCarPackageAudit.FLOW_AUDIT_TYPE);
        if(info == null) {
            throw new RuntimeException("未找到对应的流程定义信息，请先部署流程文件");
        }
        String processDefinitionKey = info.getProcessDefinitionKey();
        if(processDefinitionKey == null || processDefinitionKey.trim().isEmpty()) {
            throw new RuntimeException("流程定义Key为空，请检查流程配置");
        }
        String businessKey = audit.getId().toString();
        Map<String,Object> params = new HashMap<>();
        params.put("shopOwnerId",vo.getShopOwnerId());
        if(vo.getFinanceId() != null){
            params.put("financeId",vo.getFinanceId());
        }
        // 插入后就会在 audit 对象中存在插入后数据库中的 id，根据该 id 启动流程实例
        ProcessInstance processInstance =
                runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey, params);
        // 对审核记录（快照表）中的 instanceId 更新。
        audit.setInstanceId(processInstance.getProcessInstanceId());
        // 对审核记录进行更新（这里是后端调用后端，不存在前端传递垃圾数据，所以可以调用全量更新，但是最好不要这么做）。
        carPackageAuditService.updateBusCarPackageAudit(audit);
        // 还要将服务项的状态也修改为审核中。
        return busServiceItemMapper.changeAuditStatus(vo.getServiceItemId(),BusServiceItem.AUDITSTATUS_AUDITING);
    }

    @Override
    public int changeAuditStatus(Long serviceItemId, Integer auditstatusInit) {
        return  busServiceItemMapper.changeAuditStatus(serviceItemId, auditstatusInit);
    }
}




